<template>
  <div class="rdm-select">
    <!-- 禁用状态下显示只读输入框 -->
    <el-input
      v-if="disabled"
      v-model="displayLabelValue"
      readonly
      disabled
      class="disabled-input"
    />
		
    <!-- 非禁用状态下显示可选择的select -->
    <el-select
      v-else
      v-model="internalModelValue"
      :multiple="multiple"
      filterable
      remote
      reserve-keyword
      :placeholder="placeholder"
      remote-show-suffix
      :remote-method="remoteMethod"
      :loading="loading"
      @change="handleSelectChange"
      class="remote-select"
      clearable
      :key="refreshKey"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
        <div class="option-content">
          <span>{{ item.label }}</span>

          <span
            v-for="(key, index) in extendLabelKeys"
            :key="index"
            v-if="item.raw && item.raw[key]"
            class="option-identifier"
          >
            {{ item.raw[key] }}
          </span>
        </div>
      </el-option>
    </el-select>
  </div>
</template>

<script>
export default {
  name: "SysSelect",
  props: {
    // v-model绑定值，逗号分隔的ID（Vue2使用value而不是modelValue）
    value: {
      type: String,
      default: "",
    },
    // 显示标签，逗号分隔的名称
    displayLabel: {
      type: String,
      default: "",
    },
    // 搜索API
    api: {
      type: Function,
      required: true,
    },
    queryDistrictId: {
      type: String,
      default: "",
    },
    // 搜索字段名称
    searchName: {
      type: String,
      default: "name",
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 主键字段
    valueKey: {
      type: String,
      default: "id",
    },
    // 标签字段
    labelKey: {
      type: String,
      default: "name",
    },
    // 在选项中额外显示的标识符字段（如工号）- 可以是多个字段
    extendLabelKeys: {
      type: Array,
      default: () => [],
    },
    fixedQueryParams: {
      default: () => ({}),
    },
    // 输入框占位符
    placeholder: {
      type: String,
      default: "请输入关键词搜索",
    },
    // 如果需要，可以添加idsKey
    idsKey: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      loading: false,
      options: [],
      optionsCache: new Map(), // 缓存所有见过的选项
      internalDisplayLabel: "",
      selectedOptions: [],
      refreshKey: 0, // 用于强制重新渲染select组件
      isUserSelecting: false, // 标志位：是否正在进行用户选择操作
    };
  },
  computed: {
    // 内部模型值处理 - 多选模式下是数组，单选模式下是字符串
    internalModelValue: {
      get() {
        if (this.multiple) {
          // 多选模式返回数组
          return this.value ? this.value.split(",").filter(Boolean) : [];
        } else {
          // 单选模式返回字符串，确保空值时返回空字符串而不是其他值
          if (!this.value || this.value === "" || this.value === "0") {
            return "";
          }
          const ids = this.value.split(",").filter(Boolean);
          return ids.length > 0 ? ids[0] : "";
        }
      },
      set(value) {
        if (this.multiple) {
          // 多选模式处理数组
          const valueArray = Array.isArray(value)
            ? value
            : [value].filter(Boolean);
          this.$emit("input", valueArray.join(","));
        } else {
          // 单选模式处理单个值，确保空值正确传递
          if (value === "" || value === null || value === undefined) {
            this.$emit("input", "");
          } else {
            const valueStr = Array.isArray(value)
              ? value[0] || ""
              : value || "";
            this.$emit("input", valueStr);
          }
        }
      },
    },
    // 计算属性 - 显示的标签文本
    displayLabelValue: {
      get() {
        return this.internalDisplayLabel || this.displayLabel || "";
      },
      set(val) {
        this.internalDisplayLabel = val;
        this.$emit("update:display-label", val);
      },
    },
  },
  watch: {
    // 监听value变化，当外部修改ID时更新显示标签
    value: {
      async handler(newVal, oldVal) {
        if (newVal !== oldVal) {
          const selectedIdValues = this.getSelectedIdValues();

          // 如果是用户选择操作，不需要调用API，直接跳过
          if (this.isUserSelecting) {
            return;
          }

          // 检查是否所有ID都已经在缓存中
          const allInCache = selectedIdValues.every((id) =>
            this.optionsCache.has(id)
          );

          if (selectedIdValues.length > 0 && !allInCache) {
            // 如果有新ID不在缓存中，则重新加载
            await this.loadInitialOptions();
          } else if (selectedIdValues.length > 0) {
            // 如果所有ID都在缓存中，直接更新标签
            const selectedItems = selectedIdValues.map((id) => {
              return this.optionsCache.get(id) || { value: id, label: id };
            });
            const labels = selectedItems.map((item) => item.label);
            this.internalDisplayLabel = labels.join(",");
            this.$emit("update:display-label", labels.join(","));

            // 更新选中项选项
            this.updateSelectedOptions();
          } else {
            // 如果没有ID了，清空标签
            this.internalDisplayLabel = "";
            this.$emit("update:display-label", "");
            this.selectedOptions = [];
            this.options = [];
          }
        }
      },
      immediate: true,
    },
    // 监听displayLabel变化，同步内部状态
    displayLabel: {
      handler(newVal) {
        if (newVal !== this.internalDisplayLabel) {
          this.internalDisplayLabel = newVal;

          // 更新选中项选项以更新显示
          this.updateSelectedOptions();

          // 如果有选中的ID但displayLabel被外部更新，需要更新缓存
          const selectedIdValues = this.getSelectedIdValues();
          if (selectedIdValues.length > 0) {
            this.updateCacheWithLabels(selectedIdValues, newVal);
          }
        }
      },
      immediate: true,
    },
  },
  async mounted() {
    const selectedIdValues = this.getSelectedIdValues();

    // 确保有初始值才执行
    if (selectedIdValues.length > 0) {
      // 清空选项，确保下拉框中不显示任何内容
      this.options = [];
      await this.loadInitialOptions();

      // 更新选中项选项
      this.updateSelectedOptions();
    }
  },
  methods: {
    // 处理单选和多选的值转换
    getSelectedIdValues() {
      if (this.multiple) {
        // 多选模式，确保返回数组
        const modelValue = this.internalModelValue;
        return Array.isArray(modelValue)
          ? modelValue
          : [modelValue].filter(Boolean);
      } else {
        // 单选模式，将单个值转为数组
        const singleValue = this.internalModelValue;
        return singleValue ? [singleValue] : [];
      }
    },

    // 更新选项缓存
    updateCache(items) {
      items.forEach((item) => {
        if (item && item.value) {
          this.optionsCache.set(item.value, item);
        }
      });
    },

    // 更新所有选中项的选项
    updateSelectedOptions() {
      const selectedIdValues = this.getSelectedIdValues();

      if (selectedIdValues.length === 0) {
        this.selectedOptions = [];
        this.options = [];
        return;
      }

      // 为每个ID创建或更新选项，优先使用缓存中的数据
      this.selectedOptions = selectedIdValues.map((id) => {
        const cachedOption = this.optionsCache.get(id);

        // 如果缓存中有完整的数据，直接使用缓存的
        if (cachedOption && cachedOption.raw && !cachedOption.raw.isInitData) {
          return cachedOption;
        }

        // 如果有自定义显示标签，但只在没有完整缓存数据时才使用
        const displayLabels = this.internalDisplayLabel
          ? this.internalDisplayLabel.split(",")
          : [];
        const idIndex = selectedIdValues.indexOf(id);

        if (displayLabels.length > idIndex && displayLabels[idIndex]) {
          // 只在没有完整缓存数据时，才使用自定义标签创建新选项
          const newOption = {
            value: id,
            label: displayLabels[idIndex],
            raw: {
              [this.valueKey]: id,
              [this.labelKey]: displayLabels[idIndex],
              isInitData: true,
            },
          };

          // 只在缓存中没有或缓存数据不完整时才更新缓存
          if (
            !cachedOption ||
            (cachedOption.raw && cachedOption.raw.isInitData)
          ) {
            this.optionsCache.set(id, newOption);
          }

          return newOption;
        }

        // 如果有缓存（即使是初始数据），也优先使用
        if (cachedOption) {
          return cachedOption;
        }

        // 如果都没有，使用ID作为标签创建一个基础选项
        const fallbackOption = {
          value: id,
          label: id,
          raw: {
            [this.valueKey]: id,
            [this.labelKey]: id,
            isInitData: true,
          },
        };

        this.optionsCache.set(id, fallbackOption);
        return fallbackOption;
      });

      // 使用nextTick确保DOM更新
      this.$nextTick(() => {
        // 强制刷新选择框
        this.refreshKey = Date.now();

        // 重新创建options数组，确保包含所有选中项，但避免重复
        const existingValues = this.selectedOptions.map((opt) => opt.value);
        const newOptions = [
          ...this.selectedOptions,
          ...this.options.filter((opt) => !existingValues.includes(opt.value)),
        ];
        this.options = newOptions;
      });
    },

    // 远程搜索方法
    async remoteMethod(query) {
      if (!query) {
        // 清空搜索时，确保当前选中项仍然显示
        this.options = [];
        return;
      }

      this.loading = true;
      try {
        // 构建查询参数
        const queryParams = {
          pageNum: 1,
          pageSize: 30,
          ...this.fixedQueryParams,
          queryDistrictId,
        };
        // 使用searchName作为搜索参数
        queryParams[this.searchName] = query;

        const res = await this.api(queryParams);
        if (res && res.data) {
          let dataList = [];

          // 解析不同的数据结构
          if (res.data.list) {
            dataList = res.data.list;
          } else if (res.data.records) {
            dataList = res.data.records;
          } else if (Array.isArray(res.data)) {
            dataList = res.data;
          } else if (res.data.rows) {
            dataList = res.data.rows;
          }

          // 转换为选项格式 - 使用传入的valueKey和labelKey
          const searchResults = dataList.map((item) => ({
            value: String(item[this.valueKey]), // 使用传入的valueKey
            label: item[this.labelKey], // 使用传入的labelKey
            raw: item, // 保存原始数据
          }));

          // 更新缓存
          this.updateCache(searchResults);

          // 只显示搜索结果，不包含已选项
          this.options = searchResults;
        }
      } catch (error) {
        console.error("搜索数据失败:", error);
        this.$message.error("搜索失败");
      } finally {
        this.loading = false;
      }
    },

    // 加载初始选项数据，确保能显示已选项的标签
    async loadInitialOptions() {
      const selectedIdValues = this.getSelectedIdValues();

      if (selectedIdValues.length === 0) return;

      // 如果已有displayLabel，直接使用，无需其他操作
      if (this.displayLabel) {
        this.internalDisplayLabel = this.displayLabel;
        this.updateSelectedOptions();
        return;
      }

      // 如果没有displayLabel，调用API获取对应名称数据
      try {
        this.loading = true;
        // 构建查询参数，使用ID列表查询
        const queryParams = {
          pageNum: 1,
          pageSize: selectedIdValues.length > 10 ? selectedIdValues.length : 10,
        };

        // 添加ids参数，用于批量查询
        // if (this.idsKey) {
        //   queryParams[this.idsKey] = selectedIdValues.join(',')
        // } else {
        //   // 默认使用ids作为参数名
        //   queryParams.ids = selectedIdValues.join(',')
        // }

        const res = await this.api(queryParams);
        if (res && res.data) {
          let dataList = [];

          // 解析不同的数据结构
          if (res.data.list) {
            dataList = res.data.list;
          } else if (res.data.records) {
            dataList = res.data.records;
          } else if (Array.isArray(res.data)) {
            dataList = res.data;
          } else if (res.data.rows) {
            dataList = res.data.rows;
          }

          // 转换为选项格式，确保使用传入的valueKey和labelKey
          const initialOptions = dataList.map((item) => ({
            value: String(item[this.valueKey]), // 使用传入的valueKey
            label: item[this.labelKey], // 使用传入的labelKey
            raw: item, // 保存原始数据
          }));

          // 更新缓存，不更新options
          this.updateCache(initialOptions);

          // 只根据初始ID找到对应的名称，并更新displayLabel
          const matchedOptions = initialOptions.filter((option) =>
            selectedIdValues.includes(option.value)
          );

          const labels = matchedOptions.map((opt) => opt.label);
          if (labels.length > 0) {
            this.internalDisplayLabel = labels.join(",");
            this.$emit("update:display-label", labels.join(","));
          }

          // 更新选中项选项
          this.updateSelectedOptions();
        }
      } catch (error) {
        console.error("获取初始数据失败:", error);
      } finally {
        this.loading = false;
      }
    },

    // 处理选择变化
    handleSelectChange(val) {
      // 设置标志位，表示正在进行用户选择操作
      this.isUserSelecting = true;

      // 统一处理值
      this.internalModelValue = val;

      // 直接从val参数获取选中项信息，优先使用缓存中的完整数据
      let selectedItems = [];

      if (Array.isArray(val)) {
        // 多选模式
        selectedItems = val.map((id) => {
          const cachedItem = this.optionsCache.get(id);
          // 优先使用缓存中的完整数据（非初始数据）
          if (cachedItem && cachedItem.raw && !cachedItem.raw.isInitData) {
            return cachedItem;
          }
          // 如果没有完整缓存，使用缓存或创建基础项
          return (
            cachedItem || {
              value: id,
              label: id,
              raw: {
                [this.valueKey]: id,
                [this.labelKey]: id,
                isInitData: true,
              },
            }
          );
        });
      } else {
        // 单选模式
        if (val) {
          const cachedItem = this.optionsCache.get(val);
          // 优先使用缓存中的完整数据（非初始数据）
          if (cachedItem && cachedItem.raw && !cachedItem.raw.isInitData) {
            selectedItems = [cachedItem];
          } else {
            // 如果没有完整缓存，使用缓存或创建基础项
            const item = cachedItem || {
              value: val,
              label: val,
              raw: {
                [this.valueKey]: val,
                [this.labelKey]: val,
                isInitData: true,
              },
            };
            selectedItems = [item];
          }
        }
      }

      // 更新显示标签
      const labels = selectedItems.map((item) => item.label);
      this.internalDisplayLabel = labels.join(",");
      this.$emit("update:display-label", labels.join(","));

      // 更新选中项选项
      this.updateSelectedOptions();

      // 收集所有选中项的原始数据对象
      const rawDataList = selectedItems.map((item) => item.raw || item);

      // 确保根据模式返回正确的数据格式
      if (this.multiple) {
        // 多选模式返回数组
        this.$emit("change", rawDataList);
      } else {
        // 单选模式返回单个对象
        this.$emit("change", rawDataList.length > 0 ? rawDataList[0] : null);
      }

      // 重置标志位
      this.$nextTick(() => {
        this.isUserSelecting = false;
      });
    },

    // 辅助函数：使用新标签更新缓存
    updateCacheWithLabels(ids, labelStr) {
      // 将新的displayLabel按逗号拆分
      const newLabels = labelStr ? labelStr.split(",") : [];

      // 如果label数量与id数量匹配，更新缓存
      if (newLabels.length === ids.length) {
        // 更新缓存中的label，但只更新初始数据，不覆盖完整的API数据
        ids.forEach((id, index) => {
          const cacheItem = this.optionsCache.get(id);

          // 只在缓存中没有完整数据（isInitData为true）或没有缓存时才更新
          if (
            newLabels[index] &&
            (!cacheItem || (cacheItem.raw && cacheItem.raw.isInitData))
          ) {
            // 创建一个新对象
            const updatedItem = {
              value: id,
              label: newLabels[index],
              raw: {
                [this.valueKey]: id,
                [this.labelKey]: newLabels[index],
                isInitData: true,
              },
            };
            // 只在没有完整API数据时更新缓存
            this.optionsCache.set(id, updatedItem);
          }
        });
      }
    },

    // 缓存选中的数据，避免后续API调用
    cacheSelectedData(selectedRows) {
      if (!selectedRows || selectedRows.length === 0) return;

      selectedRows.forEach((row) => {
        const option = {
          value: String(row[this.valueKey]),
          label: row[this.labelKey],
          raw: row, // 保存完整的原始数据，不标记为isInitData
        };
        // 强制更新缓存，优先保存从弹窗中选择的正确数据
        this.optionsCache.set(option.value, option);
      });

      // 缓存数据后立即更新选中项选项，确保显示正确
      this.updateSelectedOptions();
    },
  },
};
</script>

<style scoped>
.rdm-select {
  width: 100%;
}

.remote-select {
  width: 100%;
}

.disabled-input {
  width: 100%;
  height: 100%;
}

/* 自定义选项内容样式 */
.option-content {
  width: 100%;
  padding: 2px 0;
}

.option-identifier {
  margin-left: 15px;
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 4px;
  display: inline-flex;
}

/* Element UI 样式覆盖 */
::v-deep .el-select .el-select__tags {
  max-width: 100%;
}

::v-deep .el-select .el-input__inner {
  padding-top: 5px;
  padding-bottom: 5px;
}

::v-deep .el-select .el-tag {
  font-size: 14px;
}
</style>
